<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="test">
        <p>你的姓名:{{ name }}</p>
        <p>你的年龄:{{ age}}</p>
        <p>你的爱好:{{hobby}}</p>
        <p>你的家庭住址:{{address}}</p>
    </div>
    <script>
        // 封装数据劫持的函数
        function observer(options={}){
            // 判断是否传入了选择器
            if(!options.ele) throw new Error('选择器必须传入');
            // 根据传过来的选择器获取到根元素
            const root = document.querySelector(options.ele);
            // 选择器是否能获取到元素
            if(!root) throw new Error('选择器获取不到元素');
            // 判断是否传入了data
            if(!options.data) throw new Error('data必须传入');
            // 判断data是否是对象
            if(options.data.constructor !== Object) throw new Error('data必须是对象');

            // 保存data
            const _data = {};

            const rootStr = root.innerHTML; // 保存根元素的内容
            // _data.orgin = options.data;
            // 开始劫持数据
            for(let key in options.data){
                Object.defineProperty(_data,key,{
                    get(){
                        return options.data[key];
                    },
                    set(val){
                        options.data[key] = val;
                        // 数据发生改变,重新渲染
                        render(rootStr,rootStr,_data);// 劫持完成以后做的事情 
                    }
                })
                
            }

            render(root,rootStr,_data);
            return _data;
        }


        // 封装渲染函数
        function render(root,rootStr,_data){
            // alert(rootStr)
            let str = rootStr;
            // alert(str);
            // 正则表达式
            const reg= /{{ *(\w+) *}}/g;

            const res = str.match(reg);
            // console.log(res);
            res.forEach(item=> {
                const key  = reg.exec(str)[1];
                // console.log(key);
                str = str.replace(/{{ *(\w+) *}}/,_data[key]);
            });

            // console.log(str)
            root.innerHTML = str;
            
        }
    </script>

    <script>
        // const ap = observer({
        //     ele:'#test',
        //     data:{
        //         name:'adsfdasf asdfasf',
        //         age:'fasdfsadfdsaf',
        //         hobby:['吃饭','睡觉','打豆豆'],
        //         address:'北京市'
        //     }
        // })
        const newap = observer({
            ele:'#test',
            data:{
                name:'panpan',
                age:16,
                hobby:['吃饭','睡觉','打豆豆'],
                address:'菏泽市'
            }
        })

    </script>
</body>
</html>